<?php
/*
  $Id$

  iclear design pattern
  Copyright (C) 2007 - 2009 iclear GmbH

                    All rights reserved.

  This program is free software licensed under the GNU General Public License (GPL).

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA

*************************************************************************/

  class IclearWrapperMage extends IclearWrapperBase {
    
    var $lang;
// iclear DMI -> added global order var
    var $code;
    
    var $title;
    
    var $description;
    
    var $enabled;
    
    var $order;
    
    var $orderStatusID;
    
    var $currentProductID = 0;
    
    var $specialItemID = 0;
    
    var $showPriceTax;
    
    var $otPaymentItemID = 0;
    
    /**
     * 
     * @var  Local_Iclear_Sendorderb2c_Model_Iclearpayment
     * @access protected
     */
    protected $_payment = null;
    
    /**
     * 
     * @var  Mage_Sales_Model_Quote
     * @access protected
     */
    protected $_order = null;
    
    protected $_items = array();
    
    var $addressKeysMask = array(
      'name' => '',
      'company' => '',
      'street' => 'info',
      'region' => '',
      'city' => '',
      'postcode' => '',
      'state' => '',
    );
    
    var $addressKeysUnmask = array(
      'company',
      'street',
      'region',
      'city',
      'postcode',
      'state',
    );
    
// class constructor
    function __construct(&$icCore) {
      $this->icVersion = '$Id$';
    	global $icCore;
      parent::IclearWrapperBase($icCore);
      if(!defined('IC_WRAPPER_ID')) {
      	die("Wrapper base class 4 magento not instantiated!\n");
      }
      
      $this->id = IC_WRAPPER_ID;
            
      $this->code = 'iclear';
      $lang = $icCore->getLanguage();

      $this->lang =& $lang;
      $this->_installType = 'create';
    }
    
    /**
     * Performs a SQL query
     * @param string $sql
     */
    function dbQuery($sql = '') {
    	$db = Mage::getSingleton('core/resource')
	      ->getConnection('core_write');
	return $db->query($sql);
    }
    
    /**
     * Fetch a single record as array from DB
     * @param string $sql
     */
    function dbFetchRecord($sql = '') {
      $rec = false;
      if($qry = $this->dbQuery($sql)) {
        $rec = $qry->fetch(PDO::FETCH_ASSOC);
      }
      return $rec;
    }
    
    /**
     * Last DB insert ID
     */
    function dbLastInsertID() {
      return Mage::getSingleton('core/resource')->getConnection('core_write')->lastInsertId();
    }
    
    /**
     * Entry point of iclear order processing
     */
    function process() {
    	if($this->_order) {
    		
		  	/**
		  	 * 
		  	 * @var IclearSOAP
		  	 */
				$soap = $this->icCore->getObject('IclearSOAP');
				$this->icCore->perform($soap, IC_SOAP_SENDORDER_METHOD);
    		
    	}
    }
    /**
     * set current order object
     * @return Mage_Sales_Model_Quote
     */
    function setPayment($payment = false) {
      $this->_payment =& $payment;
      $this->_order = $payment->getQuote();
    	$this->_items = $this->_order->getAllVisibleItems();
    }
    /**
     * current order object
     * @return Mage_Sales_Model_Quote
     */
    function getOrder() {
      return $this->_order;
    }
    
    /**
     * actual currency ISO3 code, EUR, e.g.
     * @return string $currency
     */
    function currency() {
      return Mage::app()->getStore()->getCurrentCurrencyCode();
    }
    /**
     * item count of current order
     * @return int $count
     */
    function orderItemCount() {
      $rv = 0;
      
      if(is_array($this->_items)) {
        $rv = sizeof($this->_items);
      }
      return $rv;
    }
    
    /**
     * Calculates the tax based on net / gros difference
     * 
     * @param double $priceNet
     * @param double $priceGros
     */
    function itemTax($priceNet = 0, $priceGros = 0) {
    	$rv = 0;
      if($priceNet && $priceGros) {
      	if($priceNet != $priceGros) {
      		$rv = sprintf('%.1f', $priceGros / ($priceNet * 0.01) - 100);
      	}
      }
    	return $rv;
    }
    
    /**
     * next item of current order
     * @return array icSoapItem
     */
    function nextOrderItem() {
      $item = false;
      $id =& $this->currentProductID;
      
      if(is_array($this->_items)) {
        if($id < sizeof($this->_items)) {
        	/**
        	 * @var $mageitem Mage_Sales_Model_Quote_Item
        	 */
          $product = $this->_items[$id]->getData();
	        $item[IC_SOAP_ITEM_NO] = $this->encodeUTF8($product['sku']);
	        $item[IC_SOAP_ITEM_TITLE] = $this->encodeUTF8($product['qty'] . ' x ' . $product['name']);
//	        $mageoptions = $mageitem->getOptions();
//	        if(is_array($mageoptions = $mageitem->getOptions())) {
//	          foreach($mageoptions AS $rec) {
//	          	$optionproduct = $rec->getProduct();
//	            $item[IC_SOAP_ITEM_TITLE] .= $this->encodeUTF8(' | ' . $rec->getName());
//	          }
//	        }
	
	        // bundling items to single article @ iclear
	        $item[IC_SOAP_ITEM_QTY] = 1;
	
	        $item[IC_SOAP_ITEM_PRICE_NET] = $product['price'] * $product['qty'];
          $item[IC_SOAP_ITEM_PRICE_GROS] =  $product['price'] * $product['qty'] + $product['tax_amount'];

        	$item[IC_SOAP_ITEM_VAT_RATE] = $product['tax_percent'];
        }
        $id++;
      }
      return $item;
    }
    
    /**
     * get all specials items from shop (shipping, coupons) as an array
     * of BasketItem formatted arrays
     * @return array 
     */
    function specialItems() {
      $items = false;
      $order = $this->getOrder();
// get shipping
			$data = $this->_order->getShippingAddress()->getData();
      if( isset($data['shipping_amount']) && $data['shipping_amount']) {
      	$item[IC_SOAP_ITEM_NO] = $this->specialItemID;
        $item[IC_SOAP_ITEM_TITLE] = $this->encodeUTF8($data['shipping_description']);
        
        $item[IC_SOAP_ITEM_PRICE_NET] = $data['shipping_amount'];
        $item[IC_SOAP_ITEM_PRICE_GROS] =  $data['shipping_amount'] + $data['shipping_tax_amount'];
        $item[IC_SOAP_ITEM_QTY] = 1;
        $item[IC_SOAP_ITEM_VAT_RATE] = $this->itemTax($item[IC_SOAP_ITEM_PRICE_NET], $item[IC_SOAP_ITEM_PRICE_GROS]);
        $items[] = $item;
      }
      
// check if coupons exists
			$data = $this->_order->getShippingAddress()->getData();
      if( isset($data['coupon_code']) && $data['coupon_code']) {
      	if($data['discount_amount']) {
	        $item[IC_SOAP_ITEM_NO] = --$this->specialItemID;
	        $item[IC_SOAP_ITEM_TITLE] = $this->encodeUTF8('Coupon:' . $data['coupon_code']);
	        $item[IC_SOAP_ITEM_PRICE_NET] = $item[IC_SOAP_ITEM_PRICE_GROS] = $data['discount_amount'];
	        $item[IC_SOAP_ITEM_QTY] = 1;
	        $item[IC_SOAP_ITEM_VAT_RATE] = '0.0'; 
        
	        $items[] = $item;
      	}
      }
      
      return $items;
    }
    
    /**
     * Get the current delivery address info from shop-system
     * @return IclearAddress
     */
    function &deliveryAddress() {
      $rv = false;
      if($order = $this->getOrder()) {
      	if(! ($mageaddress = $this->_order->getDeliveryAddress()) ) {
      		$mageaddress = $this->_order->getBillingAddress();
      	}
      	$rec = $mageaddress->getData();
        $params = array(
          IC_SOAP_ADDRESS_SALUTATION => '-1',
          IC_SOAP_ADDRESS_FIRSTNAME => $rec['firstname'],
          IC_SOAP_ADDRESS_LASTNAME => $rec['lastname'],
          IC_SOAP_ADDRESS_COMPANY => $rec['company'],
          IC_SOAP_ADDRESS_STREET => $this->parseStreet($rec['street']),
          IC_SOAP_ADDRESS_STREET_NO => $this->parseStreetNo($rec['street']),
          IC_SOAP_ADDRESS_ZIPCODE => $rec['postcode'],
          IC_SOAP_ADDRESS_CITY => $rec['city'],
          IC_SOAP_ADDRESS_COUNTRY => $rec['country_id'],
        );
        $address = $this->icCore->getObject('IclearAddress', $instance = true);
        if($address->address($params)) {
          $rv =& $address;
        }
        
      }
      return $rv;
    }
    
    /**
     * get the customer register information from shop-system
     * as an array, formatted 4 direct usage in soap call
     * @return array
     */
    function customerInfo() {
      $rv = false;
      if(!$this->customerInfo) {
	      if($order = $this->getOrder()) {
	      	$rec = $this->_order->getBillingAddress()->getData();
		    	$info = array(
						IC_SOAP_REG_CUSTOMER_ACQUISE_ID => 0, // TODO: add acquise id 2 config
						IC_SOAP_REG_CUSTOMER_BANK_ACCOUNT_ID => '',
						IC_SOAP_REG_CUSTOMER_BANK_BIC => '',
						IC_SOAP_REG_CUSTOMER_BANK_BLZ => '',
						IC_SOAP_REG_CUSTOMER_BANK_CUSTOMER => '',
						IC_SOAP_REG_CUSTOMER_BANK_IBAN => '',
						IC_SOAP_REG_CUSTOMER_BANK_NAME => '',
						IC_SOAP_REG_CUSTOMER_COMPANYNAME => $this->encodeUTF8($rec['company']),
						IC_SOAP_REG_CUSTOMER_EMAIL => $this->encodeUTF8($rec['email']),
						IC_SOAP_REG_CUSTOMER_FAX => $this->encodeUTF8($rec['fax']),
						IC_SOAP_REG_CUSTOMER_FIRSTNAME => $this->encodeUTF8($rec['firstname']),
						IC_SOAP_REG_CUSTOMER_DOB => '', // TODO: find DOB
						IC_SOAP_REG_CUSTOMER_INVOICE_CITY => $this->encodeUTF8($rec['city']),
						IC_SOAP_REG_CUSTOMER_INVOICE_COUNTRY => $rec['country_id'],
						IC_SOAP_REG_CUSTOMER_INVOICE_RECEIVER => $this->encodeUTF8($rec['firstname'] . ' ' . $rec['lastname']),
						IC_SOAP_REG_CUSTOMER_INVOICE_STREET => $this->encodeUTF8($this->parseStreet($rec['street'])),
						IC_SOAP_REG_CUSTOMER_INVOICE_STREETNO => $this->encodeUTF8($this->parseStreetNo($rec['street'])),
						IC_SOAP_REG_CUSTOMER_INVOICE_ZIPCODE => $this->encodeUTF8($rec['postcode']),
						IC_SOAP_REG_CUSTOMER_LASTNAME => $this->encodeUTF8($rec['lastname']),
						IC_SOAP_REG_CUSTOMER_PHONE => $this->encodeUTF8($rec['telephone']),
						IC_SOAP_REG_CUSTOMER_SALUTATION_ID => '-1',
						IC_SOAP_REG_CUSTOMER_EXT_CUSTOMER_ID => $rec['customer_id'],
						IC_SOAP_REG_CUSTOMER_NEWSLETTER_FLAG => '',
		    	);
		    	
		    	$this->customerInfo = $info;
	    	}

      }
      return $this->customerInfo;
    }
    
    /**
     * get or set session ID
     * @param string $sessionID
     * @return string $sessionID
     */
    function sessionID($sessionID = '') {
    	$session = Mage::getSingleton('checkout/session');
      return $sessionID ? $session->setSessionId($sessionID) : $session->getSessionId();
    }
    
    /**
     * customerID of current order
     * @return int
     */
    function customerID() {
    	$rv = 0;
    	if($this->_order) {
    		$rv = $this->_order->getCustomer()->getId();
    	}
      return $rv;
    }
    
    /**
     * get the iclear shopID from config
     * @return int
     */
    function shopID() {
    	$rv = 0;
    	if($this->_payment) {
    		$rv = $this->_payment->getConfigData('shopid');
    	}
      return $rv;
    }
    
    /**
     * language ISO2 code
     * @return string
     */
    function languageISO() {
      return strtoupper(preg_replace('/([a-z]+).*/i', "$1", Mage::app()->getLocale()->getLocaleCode()));
    }
    
    /**
     * get HTTP(s) host from shop-system
     * @param $https
     */
    function httpHost($https = false) {
      return Mage::getBaseUrl();
    }
    
    /**
     * returns the iclear URL to the iclear login page
     * @return string
     */
    function iclearURL() {
    	$rv = '';
    	$basket = $this->icCore->getBasket();
    	if($url = $basket->iclearURL()) {
    		$rv = $basket->iclearURL();
    	} 
    	return $rv;
    }
    
    /**
     * obsolete in magento
     */
    function finalizeBasket() {
    }
    
    /**
     * Abstract method which must be implemented in child classes
     */
    function storeOrder() {
    	die("Store order not implemented in enclosing instance!\n");
    }
    
		/**
		 * Add stars 2 an order accepted with status WAIT
		 * this function is called in calls from iclear server as initiator - shop environemnt only loaded throug config!
		 * @return boolean
		 */
    
    function maskOrder() {
      return true;
    }
    
    /**
     * recreates the delivery and billing information of a order
     */
    function unmaskOrder() {
      $rc = false;
      $basket = $this->icCore->getBasket();
      if($orderID = $basket->orderID()) {
      	$order = Mage::getSingleton('sales/order')->load($orderID);
//      	$billing = $order->getBillingAddress();
//        $shipping = $order->getShippingAddress();
//        foreach($this->addressKeysUnmask AS $key) {
//        	$billing->{'set' . ucfirst($key)}(($val == 'info' ? '"'.$lang->getParam('ORDER_WAITING').'"' : '"**********"'));
//        	$shipping->{'set' . ucfirst($key)}(($val == 'info' ? '"'.$lang->getParam('ORDER_WAITING').'"' : '"**********"'));
//        }
      	if($order->getId()) {
      		$payment = Mage::getSingleton('Iclear_Sendorderb2c_Model_Iclearpayment');
      		$order->setStatus($payment->getOrderState());
      		$order->addStatusToHistory(
						        $payment->getOrderState(),
						        'Pending payment accepted through iclear system!');
        	$order->save();
        }      	
      }
      return $rc;
    }
    
    /**
     * set the order state 2 cancel
     * works only with waiting orders
     * @param int $orderID
     */
    function cancelOrder($orderID = 0) {
// TODO: what's about to check the order undo result (always true correct)?
      $rc = true;
      $orderID = (int) $orderID;
      if($orderID) {
      	$order = Mage::getSingleton('sales/order')->load($orderID);
      	if($order->getId()) {
      		$order->setState(Mage_Sales_Model_Order::STATE_CANCELED);
      		$order->addStatusToHistory(
						        Mage_Sales_Model_Order::STATE_CANCELED,
						        'Canceled through iclear system!');
        	$order->save();
        }      	
      }
     return $rc;
    }
    
    /**
     * returns the shopURL where the iclear system redirects the customer finally to
     * called from iclear.php processing endpoint
     */
    function shopURL() {
    	$rv = '';
      $basket =& $this->icCore->getBasket();
      
      $path = 'checkout/onepage/';
      if($basket->orderAccepted()) {
        if($basket->status() == IC_ORDER_CANCEL) {
          $rv = Mage::getUrl($path);
        } else {
          $rv = Mage::getUrl($path . 'success');
        }
      } else {
        $lang =& $this->icCore->getLanguage();
        $rv = Mage::getUrl($path);
      }
      return $rv;
    }
    
    /**
     * Installs iclear table in DB, if not present
     */
    function setup() {
    	$this->installTable();
    }
  }
?>
